<template>
  <div class="table-search">
    <template v-if="searchColumns.length > 0">
      <el-form inline label-width="8em" size="medium" style="margin-bottom: -22px" >
        <el-form-item v-for="item in searchColumns" :key="item.key" :label="`${item.title}：`" :label-width="(item.title.length + 2) + 'em'">
          <el-date-picker
            v-if="item.type === 'time'"
            v-model="searchModelData[item.key]"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd HH:mm:ss"
            format="yyyy-MM-dd HH:mm:ss"
          ></el-date-picker>
          <el-select
            v-else-if="item.type === 'select'"
            :value="searchModelData[item.key] || ''"
            @input="$set(searchModelData, item.key, $event)"
            :placeholder="`请选择${item.title}`"
          >
            <el-option
              v-for="option in item.options"
              :key="option.value || 'all'"
              :value="option.value"
              :label="option.label"
            ></el-option>
          </el-select>
          <el-input v-else v-model="searchModelData[item.key]" :placeholder="`请输入${item.title}`"></el-input>
        </el-form-item>
        <el-form-item label>
          <el-button @click="onSearchSubmit" type="primary" size="medium">查询</el-button>
          <el-button @click="onSearchReset" type="default" size="medium">重置</el-button>
          <el-button v-if="exportApi" @click="onExport" type="default" size="medium" :disabled="tableState.total===0">导出({{tableState.total}})</el-button>
          <slot name="button"></slot>
        </el-form-item>
      </el-form>
      <br />
    </template>

    <slot name="table-header"></slot>
    <el-table
      v-loading="tableState.loading"
      :data="tableState.data"
      style="width: 100%"
      v-bind="tableProps"
      @selection-change="onSelectionChange"
    >
      <!-- header-cell-style="background-color: #f5f5f5;color: #333;font-weight: bold;text-align:center" -->
      <el-table-column v-if="selection" align="center" type="selection" width="50"></el-table-column>
      <el-table-column
        v-for="item in tableColumns"
        :key="item.dataIndex"
        :prop="item.dataIndex"
        :label="item.title"
        :align="item.align || 'center'"
        :width="item.width || null"
      >
        <template slot-scope="scope">
          <slot :name="item.dataIndex" v-bind="scope">{{(item.formatter ? item.formatter(scope.row[item.dataIndex], scope.row) : scope.row[item.dataIndex]) || '-'}}</slot>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination">
      <el-pagination
        background
        layout="total, sizes, prev, pager, next, jumper"
        :current-page="tableState.pageIndex"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="tableState.pageSize"
        :total="tableState.total"
        @size-change="onPageSizeChange"
        @current-change="onPageIndexChange"
      ></el-pagination>
    </div>
    <slot name="table-footer"></slot>
  </div>
</template>

<script>
import Http from '@/lib/http';
import { formatObjectEmpty } from '@/lib/util';
export default {
  props: {
    columns: Array,
    api: {
      type: Function,
      default: () => ({ list: [], total: 0 }),
    },
    title: String,
    selection: Boolean,
    exportApi: [String, Function],
    tableProps: Object,
  },
  data () {
    return {
      tableState: {
        pageIndex: 1,
        pageSize: 10,
        loading: false,
        data: [],
        total: 0,
      },
      searchParams: {},
      searchModelData: {},
      selectionItems: [],
    };
  },
  computed: {
    searchColumns () {
      const { columns, searchModelData, $route, searchParams } = this;
      const searchColumns = [];
      columns.forEach((column) => {
        if (column.search) {
          const search = typeof column.search === 'object' ? column.search : {};
          search.key = search.key ? search.key.toString() : column.dataIndex;
          search.column = column;
          search.type = this.getSearchType(search);
          search.title = search.title || column.title;
          console.log('search', search);
          searchColumns.push(search);
          if ($route.query[search.key] && !searchModelData[search.key]) {
            searchModelData[search.key] = searchParams[search.key] = $route.query[search.key].trim();
          }
        }
      });
      return searchColumns.sort((a, b) => (a.sort || 1) - (b.sort || 1));
    },
    tableColumns () {
      return this.columns.filter((column) => !column.hide);
    },
  },
  mounted () {
    this.getList();
  },
  watch: {
    '$route' () {
      this.onSearchSubmit();
    },
  },
  methods: {
    getSearchType (search) {
      const { column, type } = search;
      if (type) {
        return type;
      } else if (/time/i.test(column.dataIndex)) {
        return 'time';
      }
    },
    initSearchParams () {
      const { searchModelData, searchParams } = this;
      Object.keys(searchModelData).forEach((key) => {
        const value = searchModelData[key];
        if (key.indexOf(',') > -1) {
          key.split(',').forEach((key, index) => {
            searchParams[key] = Array.isArray(value) && value[index] ? value[index] : null;
          });
        } else {
          searchParams[key] = value;
        }
      });
    },

    getSearchParams () {
      const searchParams = this.searchParams;
      const query = {};
      Object.keys(searchParams).forEach(key => {
        if (searchParams[key] === null || searchParams[key] !== '') {
          query[key] = searchParams[key];
        }
      });
      return query;
    },

    async getList () {
      const { tableState } = this;
      tableState.loading = true;
      try {
        const { list, total } = await this.api(
          tableState.pageIndex,
          tableState.pageSize,
          this.getSearchParams(),
        );
        tableState.data = list;
        tableState.total = total;
      } catch (error) {

      } finally {
        tableState.loading = false;
      }
    },
    onSearchReset () {
      const { searchModelData } = this;
      Object.keys(searchModelData).forEach((key) => {
        searchModelData[key] = Array.isArray(searchModelData[key]) ? [] : '';
      });
    },
    onSearchSubmit () {
      this.initSearchParams();
      this.tableState.pageIndex = 1;
      this.getList();
    },

    onPageSizeChange (val) {
      this.tableState.pageSize = val;
      this.tableState.pageIndex = 1;
      this.getList();
    },

    onPageIndexChange (val) {
      this.tableState.pageIndex = val;
      this.getList();
    },

    onSelectionChange (val) {
      this.selectionItems = val;
      this.$emit('selection-change', val);
    },

    reload (pageIndex) {
      this.getList();
    },

    onExport () {
      if (typeof this.exportApi === 'function') {
        this.exportApi(this.getSearchParams());
      } else {
        window.open(Http.getUrl(this.exportApi, formatObjectEmpty(this.getSearchParams())));
      }
    },
  },
};
</script>

<style lang="scss">
.table-search {
  // .el-card__header {
  //   background-color: #f5f5f5;
  // }
  // .card-title {
  //   .el-icon {
  //     margin-right: 5px;
  //     font-size: 1.2em;
  //   }
  //   .operate {
  //     flex: 1;
  //     text-align: right;
  //   }
  // }
  // .search .el-card__header {
  //   padding: 10px 20px;
  // }
  // .tabs .el-button--default .number {
  //   color: red;
  // }

  .pagination {
    text-align: right;
    padding: 12px;
  }
}
</style>
